#include "Vector3.h"
#include "math.h"

using namespace std;


const Vec3	Vec3::ZERO	= Vec3( 0.0f, 0.0f, 0.0f );




// Addition
Vec3 Vec3::operator + ( const Vec3 &v ) const
{
	return Vec3( x + v.x, y + v.y, z + v.z );
}


// Subtraction
Vec3 Vec3::operator - ( const Vec3 &v ) const
{
	return Vec3( x - v.x, y - v.y, z - v.z );
}


// Dot product
float Vec3::operator * ( const Vec3 &v ) const
{
	return x * v.x + y * v.y + z * v.z;
}


// Cross product
Vec3 Vec3::operator ^ ( const Vec3 &v ) const
{
	return Vec3( y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x );
}


// Scale
Vec3 Vec3::operator * ( const float &a ) const
{
	return Vec3( x*a, y*a, z*a );
}


// Scale
Vec3 Vec3::operator / ( const float &a ) const
{
	return Vec3( x/a, y/a, z/a );
}


// Cross product
Vec3& Vec3::operator ^= ( const Vec3 &v )
{
	return ( *this = *this ^ v );
}


// Scale
Vec3& Vec3::operator *= ( const float &a )
{
	return ( *this = *this * a );
}


// Scale
Vec3& Vec3::operator /= ( const float &a )
{
	return ( *this = *this / a );
}


Vec3&	Vec3::operator += ( const Vec3 &v )
{
	x += v.x;
	y += v.y;
	z += v.z;

	return *this;
}


Vec3&	Vec3::operator -= ( const Vec3 &v )
{
	x -= v.x;
	y -= v.y;
	z -= v.z;

	return *this;
}


Vec3		Vec3::operator- () const
{
	return Vec3( -x, -y, -z );
}


bool Vec3::operator == ( const Vec3& v ) const
{
	return ( x == v.x && y == v.y && z == v.z );
}


bool Vec3::operator != ( const Vec3& v ) const
{
	return ( x != v.x || y != v.y || z != v.z );
}


// Scale
Vec3 operator * ( const float &a, const Vec3 &v )
{
	return Vec3( v.x * a, v.y * a, v.z * a );
}


// Scale
Vec3	operator / ( const float &a, const Vec3 &v )
{
	return Vec3( v.x / a, v.y / a, v.z / a );
}


// Return norm
float Vec3::Norm() const
{
	return (float)sqrt( x*x + y*y + z*z );
}


// Normalize the vector
Vec3 Vec3::Normalize()
{
	return (*this = *this / Norm());
}

float Vec3::Max() const
{
	if ( x > y && x > z )
		return x;
	else if( y > z )
		return y;
	else
		return z;
}


float Vec3::Min() const
{
	if ( x < y && x < z )
		return x;
	else if( y < z )
		return y;
	else
		return z;
}


ostream& operator << ( ostream& os, const Vec3& v )
{
	os << "( " << v.x << ", " << v.y << ", " << v.z << " )";

	return os;
}
